# Copyright (c) 2005,2006,2007 Dynamic Solutions Inc. (support@dynamic-solutions.com)
#
# This file is part of DataZoomer.
#
# DataZoomer is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# DataZoomer is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

"""Launches the DataZoomer system"""


from os.path import join
from types import ListType

class dzCgiWebVars:

    def __init__(self,req):

        # switch to binary mode on windows systems
        try:
            import msvcrt,os
            msvcrt.setmode( 0, os.O_BINARY ) # stdin  = 0
            msvcrt.setmode( 1, os.O_BINARY ) # stdout = 1
        except ImportError:
            pass

        #import cgi
        f = req.getFieldStorage()
        #self.__f = f
        for key in f.keys():
            if not self.__dict__.has_key(key):
                if type(f[key])==ListType:
                    # selection inputs have a list of MiniFieldStorage instances
                    self.__dict__[key] = ','.join(['"%s"' % item.value for item in f[key]])
                elif not f[key].filename:
                    # if button pressed, SaveBut.x=12 then add a variable SaveBut=1
                    if key[-2:]=='.x': self.__dict__[key[:-2]] = '1'
                    self.__dict__[key] = f[key].value
                else:
                    self.__dict__[key] = f[key]

    def __repr__(self):
        return 'webvars!'

    def __str__(self):
        return 'webvars: %s' % ( repr(self.__dict__) )

    def __getattr__(self,name):
        return ''

    def _clear(self):
        self.__dict__ = {}


def run_as_cgi(launcher=None,config_file=None):
    try:
        import dzsystem
        dzsystem.config_file_name = config_file
        dzsystem.site_launcher = launcher

        import dzmanager
        from fcgi import isFCGI, Accept
        counter=0
        manager = dzmanager.Manager()
        while isFCGI():
            req = Accept()
            counter=counter+1
            try:
                webvars = None
                try:
                    webvars = dzCgiWebVars(req)
                    doc = manager.respond(webvars)
                except:
                    doc = dzlaunch_exception(config_file)
            finally:
                del webvars
            req.out.write(doc)
            del doc
            req.Finish()
            del req
        manager.close()
    except:
        doc = dzlaunch_exception(config_file)
        print doc


def dzlaunch_exception(config_file):
    """
     Handle an exception in dzlaunch
      Most of this is assuming zoomer is not and cannot be setup and
      therefore is lower level than it could be
    """
    import traceback, dzconfig
    from dzerror import base_error_page, base_error_message
    exception = traceback.format_exc()
    try:
        config = dzconfig.Config(config_file)
        # Debugging
        error_mode   = config.get('error','mode','0')
        support_email = config.get('error','bug_email','')
        error_page = base_error_page
        error_msg  = base_error_message
    except: error_mode = '-1'

    # if not printing to screen, write it out here (flat file vs. db)
    if not error_mode=='0':
        f = open('../traceback', 'w')
        traceback.print_exc( file = f )
        f.close()

    if error_mode=='2':
        exception = exception.replace('\n','<br />').replace('  ','&nbsp;&nbsp;')
        exception = ''.join(error_msg).replace('<#MSG>',exception)
    elif error_mode=='-1': raise
    else:
        # send email/web service call prior to overwriting exception variable
        if error_mode=='1':
            ## bug report submission
            ##  initially an email, but the desired option
            ##  is to post to a web service (dz bug tracker)
            import dzmail
            ## zoomer is not setup and with no theme, we will send a plain text email
            dzmail.SendMail(support_email, support_email, 'DataZoomer Error', exception, 'plain' )
        exception = error_page

    hdr = ('Content-type: text/html\r\n'
           'Cache-Control: no-cache\r\n'
           '\r\n')

    doc =  '%s%s' % (hdr,exception)

    return doc


if __name__ == '__main__':
    import unittest
    class LogTest(unittest.TestCase):
        def test(self):
            run_as_cgi()
    unittest.main()
